from typing import List

from sqlalchemy import and_, select, func
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.orm import joinedload

from app.database.models import Book, User


async def get_user(session: AsyncSession, telegram_id: int) -> User:
    q = select(User).where(User.chat_id == telegram_id)

    res = await session.execute(q)

    return res.scalar()


async def get_users(session: AsyncSession) -> List[User]:
    q = select(User)

    res = await session.execute(q)

    return res.scalars().all()


async def add_user(session: AsyncSession, telegram_id: int, username: str) -> None:
    user = User(chat_id=telegram_id, username=username)

    session.add(user)

    await session.commit()


async def add_book(
    session: AsyncSession,
    book_name: str,
    description: str,
    quote: str,
    level: str,
    cover: str,
    book_file_name: str,
) -> None:
    book = Book(
        name=book_name,
        description=description,
        quote=quote,
        level=level,
        cover=cover,
        file_name=book_file_name,
    )

    session.add(book)

    await session.commit()


async def search_book(
    session: AsyncSession, genre_name: str, level: str, book_id: int = None
) -> Book:
    q = select(Book).where(
        and_(Book.level == level, Book.description.contains(genre_name))
    )

    if book_id:
        q = q.where(Book.id != book_id)

    q = q.order_by(func.random()).limit(1)

    res = await session.execute(q)

    return res.scalar()


async def get_book(
    session: AsyncSession,
    book_id: int,
) -> Book:
    q = select(Book).where(Book.id == book_id)

    res = await session.execute(q)

    return res.scalar()
